<template>
  <BasicModal
    v-bind="$attrs"
    @ok="handleSubmint"
    :width="1200"
    okText="确定"
    @register="register"
    :title="props.title"
    @visible-change="handleVisibleChange"
  >
    <!-- <div class="tag-box"> -->
    <ImpExcel @success="loadDataSuccess" dateFormat="YYYY-MM-DD">
      <div class="upload-box">
        <div class="upload-box-item">{{ fileName || '选择文件' }}</div>
        <div class="upload-box-btn">导入Excel</div>
      </div>
      <!-- <a-button class="m-3"> 导入Excel </a-button> -->
    </ImpExcel>
    <BasicTable
      v-for="(table, index) in tableListRef"
      :key="index"
      :title="table.title"
      :columns="table.columns"
      :dataSource="table.dataSource"
      :scroll="{ y: 200 }"
    >
      <template #headerCell="{ column }">
        <template v-if="column.title === 'headerSelect'">
          <a-select
            style="width: 100%"
            v-model:value="table.selectInfo[column.customIndex]"
            placeholder="请选择字段映射"
            :dropdownStyle="{ width: 600 }"
            :dropdownMatchSelectWidth="false"
          >
            <a-select-option :value="item.value" v-for="(item, i) in selectOptions" :key="i"
              ><span :class="item.register === 'True' ? 'required-style' : ''"
                >{{ item.label }}[{{ item.value }}]</span
              ></a-select-option
            >
          </a-select>
        </template>
        <template v-else>
          <HeaderCell :column="column" />
        </template>
      </template>
    </BasicTable>
    <!-- </div> -->
  </BasicModal>
</template>

<script setup lang="ts">
  import { BasicModal, useModal } from '/@/components/Modal';
  import { ImpExcel } from '/@/components/Excel';
  import { BasicTable, BasicColumn } from '/@/components/Table';
  import HeaderCell from '/@/components/Table/src/components/HeaderCell.vue';
  import { getpropertybyclass } from '/@/api/equipmentLedger/index';
  import { ref, nextTick } from 'vue';
  import { Select, SelectOption } from 'ant-design-vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { getFileHash } from '/@/utils/file/download';
  import { uploadApi } from '/@/api/system/index';

  const props = defineProps({
    title: {
      type: String,
      default: '导入',
    },
    // 获取类型参数接口入参
    classParams: {
      type: Array,
      default: () => [],
    },
    uploadParams: {
      type: Object,
      default: () => {},
    },
  });
  const tableListRef = ref<
    {
      title: string;
      columns?: any[];
      dataSource?: any[];
      selectInfo?: {};
    }[]
  >([]);
  // 选择项
  let selectOptions = ref<
    {
      label: string;
      value: string;
      register: string;
    }[]
  >([]);
  let fileName = ref('');
  // 必填项
  let registerList: any = [];
  const ASelect = Select;
  const ASelectOption = SelectOption;
  const emit = defineEmits(['success']);
  // 文件
  let file: File;
  const { notification, createMessage } = useMessage();
  const [register] = useModal();
  function loadDataSuccess(res) {
    tableListRef.value = [];
    file = res.file;
    fileName.value = file.name;
    for (const excelData of res.excelData) {
      const {
        header,
        results,
        meta: { sheetName },
      } = excelData;
      let selectInfoObj = {};
      const columns: BasicColumn[] = [];
      header.forEach((title, index) => {
        selectInfoObj[index] = undefined;
        columns.push({
          title,
          dataIndex: title,
          children: [
            {
              title: 'headerSelect',
              dataIndex: title,
              customIndex: index.toString(),
            },
          ],
        });
      });
      tableListRef.value.push({
        title: sheetName,
        dataSource: results,
        columns,
        selectInfo: selectInfoObj,
      });
    }
  }
  async function uploadApiByItem(Fields) {
    try {
      let FilesSHA = await getFileHash(file);
      let { data } = await uploadApi(
        {
          data: {
            ...(props.uploadParams || {}),
            FilesSHA: JSON.stringify([FilesSHA]),
            Fields: JSON.stringify([Fields]),
          },
          file: file,
          name: 'file',
          filename: file.name,
        },
        function onUploadProgress(_progressEvent: ProgressEvent) {},
      );
      if (data.Code === 0) {
        emit('success');
      } else {
        createMessage.error(data.Message || '上传失败');
      }
    } catch (error) {
      createMessage.error('上传失败');
    }
  }
  function handleSubmint() {
    let errorTxts: any = [];
    let FieldObj: any = {};
    for (const item of tableListRef.value) {
      let targetList: any = [];
      let selectInfoObj: any = {};
      for (const key in item.selectInfo) {
        if ([null, undefined, ''].indexOf(item.selectInfo[key]) === -1) {
          targetList.push(item.selectInfo[key]);
          selectInfoObj[key] = item.selectInfo[key];
        }
      }
      FieldObj[item.title] = selectInfoObj;
      // 检查用户是否没选择
      if (targetList.length === 0) {
        errorTxts.push(`${item.title} 至少配置一列字段映射，请检查配置`);
      } else {
        // 检查选择是否重复
        let duplicateList = getDuplicates(targetList);
        if (duplicateList.length > 0) {
          for (const iterator of duplicateList) {
            let targetDuplicate = selectOptions.value.filter((v) => iterator === v.value)[0];
            errorTxts.push(
              `${item.title} ${targetDuplicate.label}[${targetDuplicate.value}]重复，请检查导入配置`,
            );
          }
        }
        // 检查是否有必填项没选择
        for (const itemByRegister of registerList) {
          if (targetList.indexOf(itemByRegister.value) === -1) {
            errorTxts.push(
              `${item.title} ${itemByRegister.label}[${itemByRegister.value}]必须选择，请检查导入配置`,
            );
          }
        }
      }
    }
    if (errorTxts.length > 0) {
      notification.error({
        message: '提示',
        description: errorTxts.join('\n'),
        duration: null,
        style: { 'white-space': 'pre-line' },
      });
    } else {
      // 目前接口不支持多页，所以只取第一页的数据
      let targetFieldObj = FieldObj[tableListRef.value[0].title];
      // 对象 属性和值翻转
      let paramsFieldObj = {};
      for (const key in targetFieldObj) {
        paramsFieldObj[targetFieldObj[key]] = +key;
      }
      console.log(`output->paramsFieldObj`, paramsFieldObj);
      uploadApiByItem(paramsFieldObj);
    }
  }
  // 获取重复的元素
  function getDuplicates(arr) {
    arr.sort(); // 先排序
    let duplicates = [];
    for (let i = 1; i < arr.length; i++) {
      if (arr[i] === arr[i - 1]) {
        duplicates.push(arr[i]);
      }
    }
    return duplicates;
  }

  // 获取字段类型
  async function getPropertyByClass() {
    selectOptions.value = [];
    registerList = [];
    let res = (await getpropertybyclass(props.classParams)) || {};
    for (const key in res) {
      let arr = res[key].split(',');
      if (arr[1] === 'True') registerList.push({ label: arr[0], value: key, register: arr[1] });
      selectOptions.value.push({ label: arr[0], value: key, register: arr[1] });
    }
  }
  async function handleVisibleChange(visible) {
    if (visible) {
      nextTick(() => {
        getPropertyByClass();
      });
    } else {
      registerList = [];
      file = {};
      tableListRef.value = [];
      fileName.value = '';
      selectOptions.value = [];
    }
  }
</script>

<style lang="less" scoped>
  .tag-box {
    width: 100%;
    position: relative;

    min-height: 600px;
    background-color: #fff;

    .main-nav {
      position: absolute;
      top: 0;
      left: 0;
      width: 240px;
      height: 100%;
      padding: 8px;
      box-sizing: border-box;
      background-color: rgba(8, 30, 66, 0.04);
      border-radius: 3px;
    }

    .main-content {
      position: relative;
      height: 100%;
      margin-left: 260px;
    }
  }

  .required-style {
    color: red;
  }

  .upload-box {
    flex: 1;
    display: flex;
    align-items: center;
    height: 32px;
    border: 1px solid #d9d9d9;
    border-radius: 5px;
    cursor: pointer;

    .upload-box-item {
      height: 32px;
      flex: 1;
      padding: 0 10px;
      line-height: 32px;
      box-sizing: border-box;
    }

    .upload-box-btn {
      box-sizing: border-box;
      height: 32px;
      padding: 4px 15px;
      background-color: rgb(40, 97, 183);
      color: #fff;
    }
  }
</style>
